<?php

class Detalle
{
    /**
     * RFC
     * @var string 
     */
    private $curp;

    /**
     * Monto máximo autorizado para cargo
     * @var string 
     */
    private $montoMaximo;

    /**
     * Nombre completo del cliente
     * @var string 
     */
    private $nombre;

    /**
     * Cuenta banorte
     * @var string 
     */
    private $cuenta;
    private $identificacion;
    private $detalle;

    public function __construct($curp, $montoMaximo, $nombre, $cuenta, $identificacion) {
        $this->curp = mb_strtoupper(trim($curp));
        $this->montoMaximo = trim($montoMaximo);
        $this->nombre = mb_strtoupper(trim($nombre));
        $this->cuenta = trim($cuenta);
        $this->identificacion = trim($identificacion);
        $this->detalle = null;
    }

    public function getString() {
        if ($this->detalle === null) {
            $parts = array();
            $parts[] = 'D'; // Detalle
            $parts[] = $this->getReferencia();
            $parts[] = $this->getMontoMaximo();
            $parts[] = '072'; //Banco receptor
            $parts[] = $this->getNombre();
            /**
             * 01 = Cuentas Banorte
             * 03 = Tarjeta de Débito Banorte o de otros bancos   
             * 40 = CCC CLABE Banorte o de otros bancos
             */
            $parts[] = '01'; // Tipo de cuenta
            $parts[] = $this->getCuenta();
            /**
             * 1 Persona moral
             * 2 Persona fisica
             */
            $parts[] = '2'; // Persona fisica
            /**
             * 1: IFE
             * 2: Pasaporte
             * 3: Acta constitutiva o poderes
             */
            $parts[] = '1'; // IFE
            $parts[] = $this->getIdentificacion();
            $parts[] = $this->getCURP();
            /**
             * Código de divisa
             */
            $parts[] = '01'; //MXN
            $parts[] = '00'; //Código de rechazo. Cuando se envia siempre es 00
            /**
             * A = Alta
             * B = baja
             * R = Reemplazo
             */
            $parts[] = 'A';
            $parts[] = $this->getFiller();
            $this->detalle = implode('', $parts);
        }
        return $this->detalle;
    }

    private function getReferencia() {
        $referencia = $this->curp;
        return str_pad($referencia, 40);
    }

    private function getCURP() {
        $curp = $this->curp;
        return str_pad($curp, 18);
    }

    private function getMontoMaximo() {
        if ($this->montoMaximo <= 0) {
            throw new Exception('Monto máximo autorizado mayor a CERO');
        }
        $monto = number_format($this->montoMaximo, 2, '', '');
        return str_pad($monto, 15, '0', STR_PAD_LEFT);
    }

    private function getNombre() {
        $nombre = $this->nombre;
        $nombreSinAcentos = str_replace(array('Á', 'É', 'Í', 'Ó', 'Ú', 'Ñ'), array('A',
            'E', 'I', 'O', 'U', 'N'), mb_strtoupper($nombre));
        $diff = strlen($nombreSinAcentos) - mb_strlen($nombreSinAcentos);
        $nombreRelleno = str_pad(trim($nombreSinAcentos), 40 + $diff);
        return mb_substr($nombreRelleno, 0, 40);
    }

    private function getCuenta() {
        $cuenta = $this->cuenta; 
        return str_pad($cuenta, 18, '0', STR_PAD_LEFT);
    }

    private function getIdentificacion() {
        $identificacion = $this->identificacion;
        return str_pad($identificacion, 20);
    }

    private function getFiller() {
        return str_pad(' ', 16);
    }

}
